package speciality

import (
	"context"
	"encoding/json"
	"github.com/go-redis/redis/v8"
	"github.com/pkg/errors"
	"yangming-college/app/speciality/cmd/v1/api/internal/svc"
	"yangming-college/app/speciality/cmd/v1/api/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type SpecialityLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewSpecialityLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SpecialityLogic {
	return &SpecialityLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *SpecialityLogic) Speciality() (resp []types.SpecialityInfo, err error) {
	// 1、查询redis里是否有数据，如果有则返回数据，如果没有则执行以下步骤
	result, err := l.svcCtx.RedisClient.Get(context.Background(), "speciality_data").Result()
	if err != nil {
		if err == redis.Nil {
			// 2、查询所有的1、2、3级领域标签并封装到SpecialityInfo切片中
			var allSpecialities []types.SpecialityInfo
			err := l.svcCtx.DB.Table("speciality").Find(&allSpecialities).Error
			if err != nil {
				return nil, errors.Wrapf(err, "speciality v1 api Speciality error 1")
			}

			info := make([]types.SpecialityInfo, 0)
			vis := make([]bool, len(allSpecialities))
			// 获取一级领域
			for i, v := range allSpecialities {
				if v.ParentId == 0 {
					info = append(info, v)
					vis[i] = true
				}
			}

			//遍历一级领域查询二级领域
			for i, specialityl1 := range info {
				for j, specialityl2 := range allSpecialities {
					if specialityl1.Id == specialityl2.ParentId && !vis[j] {
						vis[j] = true
						//遍历二级领域查询三级领域
						for k, specialityl3 := range allSpecialities {
							if specialityl2.Id == specialityl3.ParentId && !vis[k] {
								vis[k] = true
								specialityl2.Children = append(specialityl2.Children, specialityl3)
							}
						}
						specialityl1.Children = append(specialityl1.Children, specialityl2)
					}
				}
				info[i] = specialityl1
			}
			// 3、将SpecialityInfo切片存到redis中
			jsonBytes, err := json.Marshal(info)
			if err != nil {
				return nil, errors.Wrapf(err, "speciality v1 api Speciality error 2")
			}
			err = l.svcCtx.RedisClient.Set(context.Background(), "speciality_data", jsonBytes, 0).Err()
			if err != nil {
				return nil, errors.Wrapf(err, "speciality v1 api Speciality error 3")
			}

			return info, nil
		}
		return nil, errors.Wrapf(err, "speciality v1 api Speciality error 4")
	}
	// 解析 Redis 中的数据
	err = json.Unmarshal([]byte(result), &resp)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
